#include <cassert>
#include <cstdio>
#include<pthread.h>

#include "EventLoop.h"
#include "Channel.h"
#include "Poller.h"
#include "TimerQueue.h"

__thread EventLoop * t_loopInThisThread = 0;

const int kPollTimeMs = 10000;
// 默认的一个poll超时时间

EventLoop::EventLoop() : looping_(false),
                        quit_(true),
                        callingPeningFunctors_(false),
                        threadId_(Thread::getTid()),
                       //  poller_(Poller::newDefaultPoller(this)),
                        timerQueue_(new TimerQueue(this)){
    if(!t_loopInThisThread) t_loopInThisThread = this;
    // 如果当前线程没有事件循环对象就赋值
}

EventLoop::~EventLoop() {
    assert(!looping_);
    t_loopInThisThread = nullptr;
}

EventLoop * EventLoop::getEventLoopOfCurrentThread() {
    return t_loopInThisThread;
    // 获取并返回当前线程中的事件循环
}

void EventLoop::loop() {
    assert(!looping_);
    // 这里是先判断下事件循环是否在执行
    assertInLoopThread();
    // 检查是否在正确的线程中
    looping_ = true;
    // 表示现在事件循环正在工作
    quit_ = false;

    while(!quit_){
        activeChannels_.clear();
        poller_->poll(kPollTimeMs, &activeChannels_);
        for(ChannelList::iterator it = activeChannels_.begin(); it != activeChannels_.end(); ++it){
            (*it)->handleEvent();
            // 调用对应的事件处理函数
        }

        doPendingFunctors();
        // 执行保存在pendingFunctors中的事件
    }
    looping_ = false;
    // 结束循环
}


void EventLoop::abortNotInLoopThread() {
    fprintf(stderr, "error not in thread\n");
}

void EventLoop::updateChannel(Channel *channel) {
    assert(channel->ownerLoop() == this);
    assertInLoopThread();
    poller_->updateChannel(channel);
}

void EventLoop::quit() {
    quit_ = true;
    // 结束事件循环的条件
    if(!isInLoopThread()){
        wakeup();
    }
}

TimerId EventLoop::runAt(Timestamp time, EventLoop::TimerCallback cb) {
    return timerQueue_->addTimer(cb, time, 0.0);
}

TimerId EventLoop::runAfter(double delay, EventLoop::TimerCallback cb) {
    Timestamp time(addTime(Timestamp::now(), delay));
    return runAt(time, cb);
}

TimerId EventLoop::runEvery(double interval, EventLoop::TimerCallback cb) {
    Timestamp time(addTime(Timestamp::now(), interval));
    return timerQueue_->addTimer(cb, time, interval);
}

void EventLoop::runInLoop(const EventLoop::Functor &cb) {
    if (isInLoopThread()){
        cb();
        // 如果是在当前线程(IO线程)就调用对应事件的回调函数
    }else{
        queueInLoop(cb);
        // 如果不是在IO线程就转移到IO线程调用
    }

}

void EventLoop::queueInLoop(const EventLoop::Functor &cb) {
    {
        MutexLockGuard lock(mutex_);
        pendingFunctors_.push_back(cb);
    }
    if(!isInLoopThread() || callingPeningFunctors_){
        wakeup();
        // 只有在IO线程的事件回调中才不用调用wakeup
    }
}

void EventLoop::doPendingFunctors() {
    std::vector<Functor> functors;
    callingPeningFunctors_ = true;
    // 表示现在正在执行事件回调
    {
        MutexLockGuard lock(mutex_);
        functors.swap(pendingFunctors_);
    }

    for (int i = 0; i < functors.size(); ++i){
        functors[i]();
    }
    callingPeningFunctors_ = false;
}

void EventLoop::handleRead() {

}



void EventLoop::wakeup() {

}

